<template>
    <div class="file-upload">
        <div class="file-upload-container" @click.prevent="triggerUpload" v-bind="$attrs">
         <slot v-if="fileStatus==='loading'" name="loading">
          <button class="btn btn-primary">...正在上传... </button>
          </slot> 
         <slot v-else-if="fileStatus==='success'" name="uploaded" :uploadedData ="uploadedData">
          <button class="btn btn-primary" >上传成功</button>
        </slot> 
         <slot v-else name="default">
          <button class="btn btn-primary">点击上传 </button>

        </slot> 
        </div>
        <input 
        type="file"
        class="file-input d-none"
        ref="fileInput"
        @change="handleFileChange"
        >
  <button class="btn btn-danger" v-if="fileStatus==='success'" @click="deleteFile">删除</button>
    </div>
    
</template>

<script lang="ts">
 import {defineComponent,ref,PropType,watch} from 'vue'
 import axios from 'axios';
 type UploadStatus = 'ready' | 'loading' | 'success' | 'error'
 type CheckFunction = (file:File) => boolean;
  export default defineComponent({
    name: 'Login',
    
    components: {
    
    },
    props:{
      actions:{
        type:String,
        required:true
      },
      beforeUnload:{
        type:Function as PropType<CheckFunction>
      },
      uploaded:{
        type:Object
      }
     

    },
    inheritAttrs: false,
    emits:['file-uploaded','file-uploaded-error'],
    setup(props,context) {
      const fileInput = ref<null | HTMLInputElement>(null)
      const fileStatus=ref<UploadStatus>(props.uploaded? 'success':'ready')
      const uploadedData  = ref(props.uploaded)
    
      const triggerUpload = () =>{
        
        if(fileInput.value){
        
            fileInput.value.click()
        }
      }
      watch(()=>props.uploaded,(newValue)=>{
        if(newValue){
          fileStatus.value = 'success'
          uploadedData.value = newValue
        }
        
      })
     
      const handleFileChange = (e:Event)=>{
        const currentTarget = e.target as HTMLInputElement
       
        if( currentTarget.files){
          const files = Array.from( currentTarget.files)

          if(props.beforeUnload){
            const result = props.beforeUnload(files[0])
           
            if(!result){
              return 
            }
          }
          fileStatus.value = 'loading'
          // const files = Array.from( currentTarget.files)
          // const
          // const uploadedFile = files[0]
          const formData = new FormData()
          formData.append('file',files[0])
          axios.post(props.actions,formData,{
            headers:{
              'Content-Type':'multipart/form-data'
            }
          }).then((resp:any)=>{
            fileStatus.value='success'
            context.emit('file-uploaded',resp.data)
            uploadedData.value = resp.data
            // console.log(resp.data)
          }).catch((error)=>{
            fileStatus.value = 'error'
            context.emit('file-uploaded-error','error')
          }).finally(()=>{
            if(fileInput.value){
              fileInput.value.value= ''
            }
          })

        }

      }
   
      const deleteFile = ()=>{
        uploadedData.value = {}
        fileStatus.value = 'ready'
      }
      return{
        triggerUpload,
        fileInput,
        fileStatus,
        uploadedData,
        handleFileChange,
        deleteFile
        

      }
   
    }
  })
</script>


